﻿using Admin.Core.Common.Auth;
using Admin.Core.Common.Input;
using Admin.Core.Common.Output;
using Admin.Core.Common.ParamInput;
using Admin.Core.Model.Warehouse;
using Admin.Core.Repository.Warehouse.StockIn;
using Admin.Core.Repository.Warehouse.XbcLocation;
using Admin.Core.Repository.Warehouse.XbcMeterrial;
using Admin.Core.Repository.Warehouse.XbcTypeR;
using Admin.Core.Repository.Warehouse.XbcWarehouse;
using Admin.Core.Service.Warehouse.XbcLocation.Input;
using Admin.Core.Service.Warehouse.XbcLocation.Output;
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Admin.Core.Service.Warehouse.XbcLocation
{
    public class XbcLocationService: IXbcLocationService
    {
        private readonly IUser _user;
        private readonly IMapper _mapper;
        private readonly IXbcTypeRepository _xbcTypeRepository;
        private readonly IXbcLocationRepository _xbcLocationRepository;
        private readonly IXbcWarehouseRepository _xbcWarehouseRepository;
        private readonly IXbcMaterrialRepository _xbcMaterrialRepository;
        public XbcLocationService(IUser user, IMapper mapper, IXbcLocationRepository xbcLocationRepository,
            IXbcTypeRepository xbcTypeRepository,
            IXbcWarehouseRepository xbcWarehouseRepository,
            IXbcMaterrialRepository xbcMaterrialRepository)
        {
            _user = user;
            _mapper = mapper;
            _xbcTypeRepository = xbcTypeRepository;
            _xbcMaterrialRepository = xbcMaterrialRepository;
            _xbcWarehouseRepository = xbcWarehouseRepository;
            _xbcLocationRepository = xbcLocationRepository;
        }

        /// <summary>
        /// 获取库位
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IResponseOutput> GetAsync(long id)
        {
            var result = await _xbcLocationRepository.GetAsync<XbcLocationGetOutput>(id);
            _xbcMaterrialRepository.baseRepository.Where(x => x.XbcLocationId == id).Count(out var total);
            result.CanChange = total > 0;
            return ResponseOutput.Ok(result);
        }

        public async Task<IResponseOutput> PageAsync(PageInput<XbcLocationFilterInput> input)
        {
            var key = input.Filter?.Name;
            var houseId = input.Filter?.XbcWarehouseId;
            var list = await _xbcLocationRepository.baseRepository.Select
            .WhereIf(key.NotNull(), a => a.Name.Contains(key))
            .WhereIf(houseId!=null, a=>a.XbcWarehouseId.Equals(houseId))
            .Count(out var total)
            .OrderByDescending(true, c => c.Id)
            .Page(input.CurrentPage, input.PageSize)
            .ToListAsync(a => new XbcLocationListOutput {  XbcWarehouseName = a.XbcWarehouse.Name });
            //.ToListAsync<XbcWarehouseListOutput>();

            var data = new PageOutput<XbcLocationListOutput>()
            {
                List = list,
                Total = total
            };
            return ResponseOutput.Ok(data);
        }

        public async Task<IResponseOutput> GetLocationListAsync(long id)
        {
            var ls = await _xbcLocationRepository.baseRepository.Select
                  .Where(a => a.Enabled == true && a.XbcWarehouse.XbcTypeId == id 
                  && a.XbcWarehouse.Enabled==true
                  && a.XbcWarehouse.IsDeleted==false
                  && a.XbcWarehouse.TenantId == _user.TenantId)
                  //.Where(a => a.Locations.AsSelect().Any(t => t.TenantId == _user.TenantId && t.IsDeleted==false && t.Enabled == true))
                  //.InnerJoin<XbcLocationEntity>((a, b) => a.Id == b.XbcWarehouseId && b.TenantId == _user.TenantId && b.Enabled ==true && b.IsDeleted == false)
                  .ToListAsync(a => new
                  {
                      Value = a.Id,
                      Label = a.Name
                  });

            return ResponseOutput.Ok(ls);
        }

        


        public async Task<IResponseOutput> AddAsync(XbcLocationAddInput input)
        {
            var entity = _mapper.Map<XbcLocationEntity>(input);
            entity.TenantId = _user.TenantId;
            _xbcLocationRepository.baseRepository.Where(x => x.XbcWarehouseId.Equals(input.XbcWarehouseId) && x.Name.Equals(input.Name))
                .Count(out var total);
            if (total > 0)
            {
                return ResponseOutput.NotOk("该仓库已存在相同库位！");
            }
            var id = (await _xbcLocationRepository.InsertAsync(entity)).Id;

            return ResponseOutput.Result(id > 0);
        }

        public async Task<IResponseOutput> UpdateAsync(XbLocationUpdateInput input)
        {
            if (!(input?.Id > 0))
            {
                return ResponseOutput.NotOk();
            }

            var entity = await _xbcLocationRepository.GetAsync(input.Id);
            if (!(entity?.Id > 0))
            {
                return ResponseOutput.NotOk("库位不存在！");
            }

            if (input.Enabled == false)
            {
                _xbcMaterrialRepository.baseRepository.Where(x => x.XbcLocationId == input.Id && x.Enabled == true).Count(out var c);
                if (c > 0)
                {
                    return ResponseOutput.NotOk("库位已经存在启用的物料数据，不可禁用！");
                }
            }
            _xbcLocationRepository.baseRepository.Where(x => x.Name.Equals(input.Name) && x.XbcWarehouseId.Equals(input.XbcWarehouseId)
            && x.IsDeleted == false && x.Id != input.Id)
                .Count(out var total);
            if (total > 0)
            {
                return ResponseOutput.NotOk("该仓库已存在相同库位！");
            }

            _mapper.Map(input, entity);
            await _xbcLocationRepository.UpdateAsync(entity);
            return ResponseOutput.Ok();
        }

        public async Task<IResponseOutput> SoftDeleteAsync(long id)
        {
            _xbcMaterrialRepository.baseRepository.Where(x => x.XbcLocationId == id ).Count(out var c);
            if (c > 0)
            {
                return ResponseOutput.NotOk("库位已经存物料数据，不可删除！");
            }
            var result = await _xbcLocationRepository.SoftDeleteAsync(id);
            return ResponseOutput.Result(result);
        }

        public async Task<IResponseOutput> BatchSoftDeleteAsync(long[] ids)
        {
            var result = await _xbcLocationRepository.SoftDeleteAsync(ids);
            return ResponseOutput.Result(result);
        }
    }
}
